Passed
Push — main ( c6560a...0c6882 )
by Stefan
02:35
created

FormCKEdit.js ➔ loadEditor   F

Complexity

Conditions 18

Size

Total Lines 90
Code Lines 60

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 60
dl 0
loc 90
rs 1.2
c 0
b 0
f 0
cc 18

5 Functions

Rating   Name   Duplication   Size   Complexity  
A FormCKEditor.createCustomButtons 0 9 3
A FormCKEditor.addCustomButton 0 10 4
A FormCKEditor.replaceTextArea 0 16 4
A FormCKEditor.load 0 11 4
A FormCKEditor.constructor 0 5 1

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

Complexity

Complex classes like FormCKEdit.js ➔ loadEditor often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
/** global: displayJSError */
2
/** global: CKEDITOR */
3
4
/**
5
 * Class to load, configure the CKEditor and connect to Rich Filemanager
6
 * if available.
7
 */
8
class FormCKEditor
9
{
10
    /**
11
     * Constructor get the configuration passed from PHP.
12
     */
13
    constructor(config)
14
    {
15
        this.config = config;
16
        this.oEditor = null;
17
    }
18
    
19
    /**
20
     * Load the CKEditor:
21
     * - replace the textarea and pass option from PHP configuration
22
     * - create custom buttons if specified
23
     * - set if data (content) if comes through the PHP options
24
     * - connect to Rich Filemanager if configured
25
     */
26
    load()
27
    {
28
        this.replaceTextArea();
29
        this.createCustomButtons();
30
        if (this.config.CKEditor.editorData !== undefined) {
31
            this.oEditor.setData(this.config.CKEditor.editorData);
32
        }
33
        if (this.config.RichFilemanager !== undefined) {
34
            CKEDITOR.on('dialogDefinition', (event) => {this.connectRichFilemanager(event);});
35
        }
36
    }
37
    
38
    /**
39
     * Replace the textarea and pass option from PHP configuration.
40
     * Dimensions of the textarea are saved and set in the 'instanceReady' event to the created editor
41
     */
42
    replaceTextArea()
43
    {
44
        var oTA = document.getElementById(this.config.CKEditor.editorID);
45
        if (!oTA) {
46
            if (typeof displayJSError === "function") {
47
                displayJSError('Element [' + this.config.CKEditor.editorID + 'to be replaced by CKEditor not exists!', 'error');
48
            }
49
            return;
50
        }
51
        // get initial size of textarea to replace
52
        var iHeight = oTA.offsetHeight;
53
        var iWidth = oTA.offsetWidth;
54
        this.oEditor = CKEDITOR.replace(this.config.CKEditor.editorID, this.config.CKEditor.editorOptions);
55
        // resize to desired size
56
        this.oEditor.on('instanceReady', function(event) {event.editor.resize(iWidth, iHeight);});
57
    }
58
59
    /**
60
     * create custom buttons.
61
     */
62
    createCustomButtons()
63
    {
64
        if (Array.isArray(this.config.CKEditor.customButtons)) {
65
            let length = this.config.CKEditor.customButtons.length;
66
            for (let i = 0; i < length; i++) {
67
                this.addCustomButton(this.config.CKEditor.customButtons[i]);
68
            }
69
        }
70
    }
71
    
72
    /**
73
     * add the custom button.
74
     * Button and command are only added, if the specified handler is defined.
75
     */
76
    addCustomButton(btn)
77
    {
78
        var exec = window[btn.func];
79
        if (typeof exec === "function") {
80
            this.oEditor.addCommand('cmd_' + btn.func, {exec: function(oEditor) {window[btn.func](oEditor);}});
81
            this.oEditor.ui.addButton(btn.func, {label: btn.name, command: 'cmd_' + btn.func, icon: btn.icon});
82
        } else if (typeof displayJSError === "function") {
83
            displayJSError('Handler for Custom Button [' + btn.func + '] is not defined!', 'error');
84
        }
85
    }
86
87
    /**
88
     * Connect to Rich Filemanager.
89
     * The code from the Rich Filemanager example is modified
90
     * - jQuery code is replaced by plain javascript
91
     * - dependen on the dialog/page (link, image, image-link) different folder to
92
     *   expand are set.
93
     */
94
    connectRichFilemanager(event)
95
    {
96
        var editor = event.editor;
97
        var dialogDefinition = event.data.definition;
98
        var dialogName = event.data.name;
99
        var cleanUpFuncRef = CKEDITOR.tools.addFunction(function () {
100
            let oIFrame = document.getElementById('fm-iframeCKE');
101
            if (oIFrame) {
102
                oIFrame.remove();
103
            }
104
            document.body.style.overflowY = 'scroll';
105
        });
106
            
107
        var tabCount = dialogDefinition.contents.length;
108
        for (var i = 0; i < tabCount; i++) {
109
            var dialogTab = dialogDefinition.contents[i];
110
            if (!(dialogTab && typeof dialogTab.get === 'function')) {
111
                continue;
112
            }
113
                
114
            var browseButton = dialogTab.get('browse');
115
            if (browseButton !== null) {
116
                browseButton.hidden = false;
117
                var params = 
118
                    '?CKEditorFuncNum=' + CKEDITOR.instances[event.editor.name]._.filebrowserFn +
119
                    '&CKEditorCleanUpFuncNum=' + cleanUpFuncRef +
120
                    '&langCode=' + this.config.RichFilemanager.language +
121
                    '&CKEditor=' + event.editor.name;
122
                    
123
                if (dialogName == 'link') {
124
                    params += '&expandedFolder=' + this.config.RichFilemanager.expandFolder.browseLinkURL;
125
                } else if (dialogTab.id == 'info') {
126
                    params += '&expandedFolder=' + this.config.RichFilemanager.expandFolder.browseImageURL;
127
                } else {
128
                    params += '&expandedFolder=' + this.config.RichFilemanager.expandFolder.browseImageLinkURL;
129
                }
130
                browseButton.filebrowser.rfm_path = this.config.RichFilemanager.Path + params;
131
                browseButton.onClick = function (dialog) {
132
                    editor._.filebrowserSe = this;
133
                    
134
                    let oIFrame = document.createElement('iframe');
135
                    oIFrame.id = 'fm-iframeCKE';
136
                    oIFrame.className = 'fm-modal';
137
                    oIFrame.src = dialog.sender.filebrowser.rfm_path;
138
                    document.body.append(oIFrame);
139
                    document.body.style.overflowY = 'hidden';
140
                }
141
            }
142
        }
143
    }
144
}
145